﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


// 这个的作用是将卡片和角色信息传到界面UI上面
// 但是目前不包括血条
// 2019年10月22日 进行改动
// 将固定卡改成左侧的基本4个操作
// 默认的固定卡为 1费的平A（固定存在，无法替换） 1费的加防 1费的监视 1费的反击
// 按钮有两种施放方式 点击变成正常的锁坐标（双指取消） 和 按住拖动（暂不考虑）
// 对固定卡改掉拖动卡的形式，改成按钮卡的模板（新增）
// 不参与重抽，只在每次开打时才抽到
// 使用后不丢弃
// 回合结束后不丢弃
public class PlayerProxier : MonoBehaviour
{
    private BaseEntity _baseEntity;
    private CardManager _cardManager;
    
    public GameObject ActionDeckZone;
    
    public delegate void DoubleNumListenerDelegate(int currentLife, int maxLife);
    public delegate void SingleNumListenerDelegate(int num);
    
    // 一些监控器
    public SingleNumListenerDelegate DeckCardNumListener;
    public SingleNumListenerDelegate RecycleCardNumListener;
    public SingleNumListenerDelegate DrawCardNumListener;
    public SingleNumListenerDelegate MoneyCheckListener;
    public SingleNumListenerDelegate APNumListener;
    public SingleNumListenerDelegate FPNumListener;
    
    public DoubleNumListenerDelegate LifeCheckListener;

    public PlayerEntityData entityData;
    public bool isHoldingCard;

    public GameObject[] FixedSlots;

    private int fixedCount = 0;

    private bool isFixedCardDraw = false;

    private SectorSort _sectorSort;
    // 固定卡卡组

    private void Awake()
    {
        if (GameObject.FindObjectsOfType<PlayerProxier>().Length > 1)
        {
            Destroy(this.gameObject);
        }
        else
        {
            DontDestroyOnLoad(this);   
        }
    }

    private void SortSectorDeck()
    {
        if (_sectorSort == null)
        {
            _sectorSort = GetActionDeckZone().GetComponent<SectorSort>();
        }

        _sectorSort.SortCards();
    }

    public void Initial()
    {
        isHoldingCard = false;

        InitCardManager();
        
        GameObject.FindGameObjectWithTag(StaticDataManager.GAME_SESSION_TAG).GetComponent<GameSession>().BattleStart();
        BattleStart();
    }
    
    private void InitCardManager()
    {
        SetDefaultState();

        _cardManager = new CardManager(_baseEntity);
        _cardManager.InitialDeck(entityData);
        
        if (entityData.currentDeck.Count <= 0)
        {
            _cardManager.SetDefaultDeck();
        }
        
        // 遍历所有的卡片 然后设置他们的拥有者
        foreach (GameObject cardInstance in _cardManager.cardInstances[DeckType.Action])
        {
            cardInstance.GetComponent<DragCard>().SetPlayerProxier(this);
        }
    }
    
    #region 基本流程单元

    public void SetDefaultState()
    {
//        entityData.maxHP = StaticDataManager.DEFAULT_MAX_HP;
//
//        entityData.HP = StaticDataManager.DEFAULT_MAX_HP;
//        entityData.money = StaticDataManager.DEFAULT_CURRENT_MONEY;
//
//        entityData.FP = StaticDataManager.DEFAULT_MAX_FP;
//        entityData.maxFP = StaticDataManager.DEFAULT_MAX_FP;
//
//        entityData.AP = StaticDataManager.DEFAULT_MAX_AP;
//        entityData.maxAP = StaticDataManager.DEFAULT_MAX_AP;
//
//        entityData.MP = StaticDataManager.DEFAULT_MAX_MP;
//        entityData.maxMP = StaticDataManager.DEFAULT_MAX_MP;
//
//        entityData.cardDrawNum = 5;
        
        _baseEntity._hp = entityData.HP;
        _baseEntity._hp_max = entityData.maxHP;
        
        _baseEntity._fp = entityData.FP;
        _baseEntity._fp_max = entityData.maxFP;
        
        _baseEntity._ap = entityData.AP;
        _baseEntity._ap_max = entityData.maxAP;
        
        _baseEntity._mp = entityData.MP;
        _baseEntity._mp_max = entityData.maxMP;

        _baseEntity._money = entityData.money;
    }

    public void SetBaseEntity(BaseEntity baseEntity)
    {
        this._baseEntity = baseEntity;
    }

    public void RemoveCardFromDeckZone(GameObject cardInstance)
    {
        cardInstance.transform.localScale = Vector3.zero;
        cardInstance.transform.SetParent(null);

        SortSectorDeck();
    }

    public void AddCardInstanceToDeckZone(GameObject cardInstance)
    {
        if (cardInstance.GetComponent<BasicCard>().belongDeckType == DeckType.Action)
        {
            cardInstance.transform.SetParent(GetActionDeckZone().transform);
            cardInstance.transform.localScale = StaticDataManager.CARD_SIZE_RAW;

            SortSectorDeck();
        }
        else
        {
            var card = cardInstance.GetComponent<IconCard>();
            card.SetBelongSlot(GetFixSlot()[fixedCount]);
            card.BindCardToButton();
            
            fixedCount = (fixedCount + 1) % GetFixSlot().Length;
            
            cardInstance.transform.SetParent(GetFixSlot()[fixedCount].transform);
        }
        
    }
    #endregion

    #region 回合中的卡牌
    
    public void BattleStart()
    {
        isFixedCardDraw = false;
        GetFixSlot(true);
        _cardManager.BattleStart();

        FlushAllUI();
        GameObject.FindGameObjectWithTag("BattleUI").GetComponent<BattleUIManager>().BindListener();
    }

    public void FlushAllUI()
    {
        try
        {
            DeckCardNumListener?.Invoke(entityData.currentDeck.Count);
        
            DrawCardNumListener?.Invoke(_cardManager.remainDeckInstances[DeckType.Action].Count);
            RecycleCardNumListener?.Invoke(_cardManager.recycleDeckInstances[DeckType.Action].Count);

            APNumListener?.Invoke(_baseEntity._ap);
            FPNumListener?.Invoke(_baseEntity._fp);
            LifeCheckListener?.Invoke(_baseEntity._hp, _baseEntity._hp_max);
            MoneyCheckListener?.Invoke(_baseEntity._money);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }

    public GameObject GetActionDeckZone()
    {
        if (ActionDeckZone == null)
        {
            ActionDeckZone = GameObject.FindGameObjectWithTag(StaticDataManager.ACTION_DECK_ZONE_TAG);
        }

        return ActionDeckZone;
    }

    public GameObject[] GetFixSlot(bool isForce = false)
    {
        if (FixedSlots == null || FixedSlots[0] == null || isForce)
        {
            FixedSlots = new GameObject[4];
            
            GameObject slotZone = GameObject.FindGameObjectWithTag(StaticDataManager.SLOT_ZONE_TAG);
            if (slotZone == null)
            {
                return null;
            }
            
            for (int i = 0; i < slotZone.transform.childCount; i++)
            {
                FixedSlots[i] = slotZone.transform.GetChild(i).gameObject;
            }
        }

        return FixedSlots;
    }
    
    public void DisplayPlayerCards()
    {
        // 然后从 remain 区 Action 类 抽取 [] 张
        Debug.Log("准备从 Remain 区 Action 类 抽取卡牌");

        entityData.AP = entityData.maxAP;
        entityData.MP = entityData.maxMP;
        entityData.FP = entityData.maxFP;

        int drawCards = 0;
        while (drawCards < entityData.cardDrawNum)
        {
            PickCardFromRemainDeck(DeckType.Action);
            drawCards += 1;
        }

        if (drawCards > 7)
        {
            GetActionDeckZone().GetComponent<GridLayoutGroup>().spacing = new Vector2((drawCards - 1) * -10f, 0);
        }
        else
        {
            GetActionDeckZone().GetComponent<GridLayoutGroup>().spacing = new Vector2(10, 0);
        }
        
        Debug.Log($"当前Action区应有 {_cardManager.currentDeckInstances[DeckType.Action].Count} 张卡");

        _cardManager.currentDeckInstances[DeckType.Action].Sort(
            (a, b) => a.GetComponent<DragCard>().pairData.cardData.cardID
                .CompareTo(b.GetComponent<DragCard>().pairData.cardData.cardID));

        // 然后从 remain 区 Fixed 类 抽取 [] 张
        if (!isFixedCardDraw)
        {
            Debug.Log("TODO 准备从 Remain 区 Fixed 类 抽取卡牌");
            drawCards = 0;
            while (drawCards < GetFixSlot().Length)
            {
                PickCardFromRemainDeck(DeckType.Fixed);
                drawCards += 1;
            }
            
            Debug.Log($"当前Fixed区应有 {_cardManager.currentDeckInstances[DeckType.Fixed].Count} 张卡");
            
            isFixedCardDraw = true;
        }
        
        Debug.Log($"当前正将卡牌设置到界面中");
        
        foreach (GameObject card in _cardManager.currentDeckInstances[DeckType.Action])
        {
            AddCardInstanceToDeckZone(card);
        }
        
        foreach (GameObject card in _cardManager.currentDeckInstances[DeckType.Fixed])
        {
            AddCardInstanceToDeckZone(card);
        }
        
        FlushAllUI();
    }

    public void TurnEnd()
    {
        Debug.Log("回合结束，准备扔掉手头上的卡牌");
        Debug.Log("正在丢弃 Action 类的卡牌");
        DiscardHolingCardInstances(DeckType.Action);
        Debug.Log("正在丢弃 Fixed 类的卡牌");
        DiscardHolingCardInstances(DeckType.Fixed);
    }

    /// <summary>
    /// 丢弃手上所有的卡牌
    /// 需要指定卡牌类型
    /// </summary>
    public void DiscardHolingCardInstances(DeckType deckType)
    {
        while (_cardManager.currentDeckInstances[deckType].Count > 0)
        {
            GameObject card = _cardManager.currentDeckInstances[deckType].Pop();

            DiscardCardInstance(card, deckType);
        }
    }
    
    /// 丢弃指定的卡牌实例到回收区
    /// 需要根据卡牌类型丢弃到哪个区
    public void DiscardCardInstance(GameObject cardInstance, DeckType deckType)
    {
        RemoveCardFromDeckZone(cardInstance);
        _cardManager.DiscardCard(cardInstance, deckType);

        FlushAllUI();
    }

    /// <summary>
    /// 从持卡区卡顶抽取一张卡
    /// 需要指定抽哪个区的卡
    /// </summary>
    public void PickCardFromRemainDeck(DeckType deckType)
    {
        
        Debug.Log("从抽卡区抽卡");

        bool isCanDrawCard = false;
        if (_cardManager.remainDeckInstances[deckType].Count > 0)
        {
            Debug.Log("从抽卡区有卡牌剩余，可以抽卡");
            isCanDrawCard = true;
        }
        else
        {
            Debug.Log("从抽卡区没有卡牌剩余");
            if (_cardManager.recycleDeckInstances.Count > 0)
            {
                Debug.Log("但是回收区有卡牌，回收一下回收区");
                RecycleCard(deckType);
                if (_cardManager.remainDeckInstances[deckType].Count > 0)
                {
                    Debug.Log("从抽卡区有卡牌剩余，可以抽卡");
                    isCanDrawCard = true;
                }
                else
                {
                    isCanDrawCard = false;   
                }
            }
        }
        
        if (isCanDrawCard)
        {
            GameObject card = ListHelper.Pop(_cardManager.remainDeckInstances[deckType]);
            _cardManager.currentDeckInstances[deckType].Add(card);
        }
        else
        {
            Debug.Log("回收区没有卡，无法继续抽卡");
        }

        FlushAllUI();
    }


    /// <summary>
    /// 回收回收区的卡牌到持卡区
    /// </summary>
    public void RecycleCard(DeckType deckType)
    {
        while (_cardManager.recycleDeckInstances[deckType].Count > 0)
        {
            _cardManager.remainDeckInstances[deckType].Add(_cardManager.recycleDeckInstances[deckType].Pop());
        }

        _cardManager.ShufflerRemainDeck(deckType);
        
        FlushAllUI();
    }
    #endregion
}
